function isArray(arg) {
    if (Array.isArray) {
        return Array.isArray(arg);
    }
    return objectToString(arg) === '[object Array]';
}

function isBoolean(arg) {
    return typeof arg === 'boolean';
}

function isNull(arg) {
    return arg === null;
}

function isNullOrUndefined(arg) {
    return arg == null;
}

function isNumber(arg) {
    return typeof arg === 'number';
}

function isString(arg) {
    return typeof arg === 'string';
}

function isSymbol(arg) {
    return typeof arg === 'symbol';
}

function isUndefined(arg) {
    return arg === void 0;
}

function isRegExp(re) {
    return objectToString(re) === '[object RegExp]';
}

function isObject(arg) {
    return typeof arg === 'object' && arg !== null;
}

function isDate(d) {
    return objectToString(d) === '[object Date]';
}

function isError(e) {
    return (objectToString(e) === '[object Error]' || e instanceof Error);
}

function isFunction(arg) {
    return typeof arg === 'function';
}

function isTrueEmpty(obj) {
    if (obj === undefined || obj === null || obj === '') return true;
    if (isNumber(obj) && isNaN(obj)) return true;
    return false;
}

function isPrimitive(arg) {
    return arg === null ||
        typeof arg === 'boolean' ||
        typeof arg === 'number' ||
        typeof arg === 'string' ||
        typeof arg === 'symbol' ||  // ES6 symbol
        typeof arg === 'undefined';
}

function objectToString(o) {
    return Object.prototype.toString.call(o);
}

export default {
    isArray,
    isBoolean,
    isNull,
    isNullOrUndefined,
    isNumber,
    isString,
    isSymbol,
    isUndefined,
    isRegExp,
    isObject,
    isDate,
    isError,
    isFunction,
    isTrueEmpty,
    isPrimitive
};
